;
if(typeof w3c === "undefined") {w3c={}};
if(typeof w3c.CSSStyleUtilities === "undefined") {w3c.CSSStyleUtilities={}};

w3c.CSSStyleUtilities = {
	/*loadcss: function(url){
		var something_went_wrong = "Error loading stylesheets. Expected an array of style urls or a single url to a stylesheet for this component.";
		var stylesheets = window.loaded_stylesheets;
		var styles = url||this["@stylesheets"];
		if(!styles) {return;}
		
		if (!stylesheets) {
			window.loaded_stylesheets = {};
			stylesheets = window.loaded_stylesheets;}
		if(styles) {
			if(styles instanceof Array) {
				for(var i=0; i<=styles.length-1; i++) {
					if (!stylesheets[styles[i]]) {
						this.loadcss(styles[i]);
					}
				}
			}
			else if(typeof styles === "string") {
				var headID = document.getElementsByTagName("head")[0];
		        var cssNode = document.createElement('link');
		        cssNode.type = 'text/css';
				cssNode.setAttribute("jscomponent", this.namespace||"");
				cssNode.setAttribute("jstype", this.classname||"");
		        cssNode.rel = 'stylesheet';
		        cssNode.href = this.resourcepath(styles);
		        cssNode.media = 'screen';
		        headID.appendChild(cssNode);
				stylesheets[styles] = cssNode;
				return stylesheets[styles];
			}
		}
		else {}
    },*/
	
	loadcss: function(url){
		var something_went_wrong = "Error loading stylesheets. Expected an array of style urls or a single url to a stylesheet for this component.";
		var stylesheets = window.loaded_stylesheets;
		var styles = url||this["@stylesheets"];
		var self=this;
		
		if(!styles) {return;}
		
		if (!stylesheets) {
			window.loaded_stylesheets = {};
			stylesheets = window.loaded_stylesheets;}
		if(styles) {
			if(styles instanceof Array) {
				for(var i=0; i<=styles.length-1; i++) {
					if (!stylesheets[styles[i]]) {
						this.loadcss(styles[i]);
					}
				}
			}
			else if(typeof styles === "string" && styles.indexOf("http://") != 0) {
				var head = document.getElementsByTagName("head")[0];
				var stylenode= document.createElement('style');
				    stylenode.setAttribute("type", 'text/css');
					stylenode.setAttribute("rel", 'stylesheet');
					stylenode.setAttribute("media", 'all');
					stylenode.setAttribute("component", this.namespace||"");
					head.appendChild(stylenode);
					stylesheets[styles] = stylenode;
					$.ajax({
						url: this.resourcepath(styles), 
						complete: function(xhr){
							if (xhr.status == 200) {
								var _cssText = self.cssTransform(xhr.responseText);
								self.setCssTextAttribute(_cssText, stylenode);								
							}
						}
					});
			}
			else if(styles && styles.indexOf("http:") == 0){
				var headID = document.getElementsByTagName("head")[0];
		        var cssNode = document.createElement('link');
		        cssNode.type = 'text/css';
				cssNode.setAttribute("component", this.namespace||"");
		        cssNode.rel = 'stylesheet';
		        cssNode.href = this.resourcepath(styles);
		        headID.appendChild(cssNode);
				stylesheets[styles] = cssNode;
			}
			else{
				try{console.warn("Unable to resolve path to stylesheet. Invalid uri: '" + styles + "'")} catch(e){}
			}
		}
		else {}
    },
	
	setCssTextAttribute : function(_cssText, stylenode){
		if (stylenode && stylenode.styleSheet) {
            stylenode.styleSheet.cssText = _cssText;
        }
        else {
            stylenode.appendChild(document.createTextNode(_cssText));
        }
	},
	
	cssTransform : function(_cssText){
		return _cssText;
	},
	
	removeClasses : function (cssSelectorOrArray, classes) {
		var elements = (cssSelectorOrArray instanceof Array) ? 
			cssSelectorOrArray : this.querySelectorAll(cssSelectorOrArray);
        for(var i=0; i<=elements.length-1; i++) {
			for (var j = 0; j <= classes.length - 1; j++) {
				this.removeClass(classes[j],elements[i]);
			}
		}
	},
	
	setStyles : function(styles, element) {
		element = element||this.element;
        var camelizedStyles = {}; //ex: uses marginTop not margin-top
        for(var k in styles) { camelizedStyles[xCamelize(k)] = styles[k];}
	    styles = camelizedStyles;
        var elementStyle = element.style, match;

        for (var property in styles) {
			if (property === 'opacity') {
				this.setOpacity(styles[property], element);
			}
			else {
				elementStyle[(property == 'float' || property == 'cssFloat') ? (typeof(elementStyle.styleFloat === "undefined") ? 'cssFloat' : 'styleFloat') : property] = styles[property];
			}
		}
        return element;
	},
	
	setOpacity: function(value, element) {
        element = element||this.element;
        element.style.opacity = (value == 1 || value === '') ? 
            '' : (value < 0.00001) ? 0 : value;
        return element;
    },
	
	getStyle : function (cssRule,element) {
        element = element||this.element;
		var val = "";
		cssRule = cssRule.toLowerCase();
		if (document.defaultView && document.defaultView.getComputedStyle) {
			val = document.defaultView.getComputedStyle(element, "").getPropertyValue(cssRule);
		}
		else if (element.currentStyle) {
			if (element.filters && /^opacity$/.test(cssRule)) {
				var alpha = element.filters["DXImageTransform.Microsoft.Alpha"] || element.filters.alpha || {};
				val = (alpha.opacity || 100) / 100;
			}
			else {
				cssRule = cssRule.replace(/^float$/, "styleFloat").replace(/\-(\w)/g, function (match, p1) {
					return p1.toUpperCase();
				});
				val = element.currentStyle[cssRule];
			}
			if (val === "auto" && /^(width|height)$/.test(cssRule) && element.currentStyle.display !== "none") {
				val = element["offset" + cssRule.charAt(0).toUpperCase() + cssRule.substr(1)] + "px";
			}
		}
		return val;
	},
	
	up : function(classname, element){
	  	classname = classname.replace(".","");
	  	element   = element||this.element;
	  	while(element && !this.hasClass(classname,element)){
	  		element=element.parentNode;
		};
	  	return element;
	},
	
	down : function(classname, element){
		element   = element||this.element;
	  	return this.querySelector(classname, element);
	},
	
	addClass: function(classname, element) {
		element = element||this.element;
		
		if (element) {
			var s = '';
			if (element.className.length && element.className.charAt(element.className.length - 1) != ' ') {
				s = ' ';
			}
			if (!this.hasClass(classname, element)) {
				element.className += s + classname;
				return true;
			}
		}
		return false;
	},
	
	hasClass : function (classname, element) {
	  element = element || this.element;
	  if (!element || element.className=='') return false;
	  var re = new RegExp("(^|\\s)"+classname+"(\\s|$)");
	  return re.test(element.className);
	},
	
	removeClass : function(classname, element){
		element = element || this.element;
        if (!element) { return false;};
        element.className = element.className.replace(
			new RegExp("(^|\\s)" + classname + "(\\s|$)", 'g'), function(str, p1, p2){
            return (p1 == ' ' && p2 == ' ') ? ' ':'';
        });
        return true;
	},
	
	createStyleDocument : function (callback) {
		if(!window.loadedstylesheets) {
			window.loadedstylesheets = {};
		}
		if(window.loadedstylesheets[this.namespace]) {return;}
		var cssCode = this.cssText;
		if(!cssCode || cssCode.length <= 0) { return};
		cssCode = this.parseTemplate(this.cssText,{});
		if(!cssCode) {
			//console.log("cssCode parsed")
			throw new Error(this.namespace + "#createStyleDocument() encountered an error while trying\
			to run this.parseTemplate(cssCode) on the following css:\n" + cssCode);
		}
		//http://yuiblog.com/blog/2007/06/07/style/
		//http://kentbrewster.com/creating-dynamic-stylesheets/
		//http://www.javascriptkit.com/domref/stylesheet.shtml
		this.stylesheet = document.createElement('style');
		this.stylesheet.setAttribute("type", 'text/css');
		this.stylesheet.setAttribute("rel", 'stylesheet');
		this.stylesheet.setAttribute("media", 'screen');
		this.stylesheet.setAttribute("jscomponent", this.namespace||"");
		this.stylesheet.setAttribute("jstype", this.classname||"");
		
		document.getElementsByTagName("head")[0].appendChild(this.stylesheet);
        if (this.stylesheet.styleSheet) {
            this.stylesheet.styleSheet.cssText = cssCode;
        }
        else {
            this.stylesheet.appendChild(document.createTextNode(cssCode));
        }
		window.loadedstylesheets[this.namespace] = true;
		//this.constructor.prototype.createStyleDocument = function(){};
//		setTimeout(callback, 30); 
		return this.stylesheet;
	},
	
	getCssRule : function(ruleName, deleteFlag){
		ruleName=ruleName.toLowerCase();                       	// Convert test string to lower case.
		if (document.styleSheets) {                            	// If browser can play with stylesheets
//	      for (var i=0; i<document.styleSheets.length; i++) { 	// For each stylesheet
//	         var styleSheet=document.styleSheets[i];          	// Get the current Stylesheet
			 var styleSheet = this.stylesheet;
	         var ii=0;                                        	// Initialize subCounter.
	         var cssRule=false;                               	// Initialize cssRule. 
	         do {                                             	// For each rule in stylesheet
	            if (styleSheet.cssRules) {                    	// Browser uses cssRules?
	               cssRule = styleSheet.cssRules[ii];         	// Yes --Mozilla Style
	            } else {                                      	// Browser usses rules?
	               cssRule = styleSheet.rules[ii];            	// Yes IE style. 
	            }                                             	// End IE check.
	            if (cssRule)  {                               	// If we found a rule...
	               if (cssRule.selectorText.toLowerCase()==ruleName) { //  match ruleName?
	                  if (deleteFlag=='delete') {             	// Yes.  Are we deleteing?
	                     if (styleSheet.cssRules) {           	// Yes, deleting...
	                        styleSheet.deleteRule(ii);        	// Delete rule, Moz Style
	                     } else {                             	// Still deleting.
	                        styleSheet.removeRule(ii);        	// Delete rule IE style.
	                     }                                    	// End IE check.
	                     return true;                         	// return true, class deleted.
	                  } else {                                	// found and not deleting.
	                     return cssRule;                      	// return the style object.
	                  }                                       	// End delete Check
	               }                                          	// End found rule name
	            }                                             	// end found cssRule
	            ii++;                                         	// Increment sub-counter
	         } while (cssRule)                                	// end While loop
//	      }                                                   	// end For loop
	   }                                                      	// end styleSheet ability check
	   return false;                                          	// we found NOTHING!
	},                                                         	// end getCSSRule 

	removeCssRule : function(ruleName){							// Delete a CSS rule   
	   return this.getCssRule(ruleName,'delete');            	// just call getCSSRule w/delete flag.
	},                                                         	// end killCSSRule
	
	addCssRule : function(ruleName){
		if (document.styleSheets) {                            	// Can browser do styleSheets?
	      if (!this.getCssRule(ruleName)) {                  	// if rule doesn't exist...
	         if (this.stylesheet.addRule) {           			// Browser is IE?
	            this.stylesheet.addRule(ruleName, null,0);		// Yes, add IE style
	         } else {                                         	// Browser is IE?
	            this.stylesheet.insertRule(ruleName+' { }', 0); // Yes, add Moz style.
	         }                                                	// End browser check
	      }                                                   	// End already exist check.
	   }                                                      	// End browser ability check.
	   return this.getCssRule(ruleName);  
	}
};